/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pa165.web;

import cz.muni.fi.pa165.portalnahouby.api.dto.PickerDTO;
import cz.muni.fi.pa165.portalnahouby.api.serviceinterface.PickerService;
import cz.muni.fi.pa165.portalnahouby.implementation.util.Crypto;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpSession;
import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidationErrors;
import org.springframework.orm.jpa.JpaSystemException;

/**
 *
 * @author Lukas Marica
 */
@DoesNotRequireLogin
@UrlBinding( "/security/{$event}")
public class SecurityActionBean implements ActionBean {

    private ActionBeanContext context;
    @Validate(required = true, on = "submitLogin")
    private String userLogin;
    @Validate(required = true, on = "submitLogin")
    private String password;
    @SpringBean
    private PickerService service;

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }

    public Resolution login() {
        return new ForwardResolution("/login.jsp");
    }

    public Resolution logout() {
        HttpSession session = getContext().getRequest().getSession();
        session.setAttribute("loggedIn", false);
        session.setAttribute("loggedUser", null);
        return new RedirectResolution("/index.jsp");
    }

    public Boolean getIsLoggedIn() {
        Boolean loggedIn = (Boolean) getContext().getRequest().getSession().getAttribute("loggedIn");
        return (loggedIn != null && loggedIn);
    }

    public Boolean getIsAdminLoggedIn() {
        Boolean loggedIn = (Boolean) getContext().getRequest().getSession().getAttribute("loggedIn");
        PickerDTO loggedUser = (PickerDTO) getContext().getRequest().getSession().getAttribute("loggedUser");
        return (loggedIn != null && loggedIn && loggedUser != null && loggedUser.getIsAdmin());
    }

    public Long getCurrentUserID() {
        PickerDTO loggedUser = (PickerDTO) getContext().getRequest().getSession().getAttribute("loggedUser");
        if (loggedUser != null) {
            return loggedUser.getId();
        } else {
            return null;
        }
    }

    public Boolean isCurrentUserID(Long id) {
        PickerDTO loggedUser = (PickerDTO) getContext().getRequest().getSession().getAttribute("loggedUser");
        if (loggedUser != null) {
            return loggedUser.getId().equals(id) || getIsAdminLoggedIn();
        } else {
            return false;
        }
    }

    public String getCurrentLogin() {
        PickerDTO loggedUser = (PickerDTO) getContext().getRequest().getSession().getAttribute("loggedUser");
        return (loggedUser != null) ? loggedUser.getLogin() : "";
    }

    public Resolution submitLogin() throws NoSuchAlgorithmException, UnsupportedEncodingException {
        HttpSession session = getContext().getRequest().getSession();
        PickerDTO picker = service.findPickerByLoginPass(userLogin, Crypto.encode(password));

        if (picker != null) {
            session.setAttribute("loggedIn", true);
            session.setAttribute("loggedUser", picker);
        } else {
            ValidationErrors errors = new ValidationErrors();
            errors.add("name", new LocalizableError("login.failed"));
            getContext().setValidationErrors(errors);          
            return new ForwardResolution(this.getClass(), "login");
        }

        return new RedirectResolution("/index.jsp");
    }
    private PickerDTO picker;

    public PickerDTO getPicker() {
        return picker;
    }

    public void setPicker(PickerDTO picker) {
        this.picker = picker;
    }

    public Resolution register() {
        return new ForwardResolution("/registration.jsp");
    }

    public Resolution submitRegister() throws NoSuchAlgorithmException, UnsupportedEncodingException {
        ValidationErrors errors = new ValidationErrors();
        if (picker == null){
             errors.add("name", new LocalizableError("picker.loginNull"));
             errors.add("name", new LocalizableError("picker.nameNull"));
             errors.add("name", new LocalizableError("picker.surnameNull"));
             errors.add("name", new LocalizableError("picker.passwordNull"));
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();
        } else{
            if (picker.getLogin() == null){
                errors.add("name", new LocalizableError("picker.loginNull"));
            }
            if (picker.getName() == null){
                errors.add("name", new LocalizableError("picker.nameNull"));
            }
            if (picker.getSurname() == null){
                errors.add("name", new LocalizableError("picker.surnameNull"));
            }
            if (picker.getPass() == null){
                errors.add("name", new LocalizableError("picker.passwordNull"));
            }
           if(!errors.isEmpty()){
               getContext().setValidationErrors(errors);
               return getContext().getSourcePageResolution();
           }
        }
        if (picker.getIsAdmin() == null) {
            picker.setIsAdmin(false);
            }
        String plainPass = picker.getPass();
        picker.setPass(Crypto.encode(picker.getPass()));
        try {
            service.addPicker(picker);
            
        } catch (JpaSystemException jse) {
            errors.add("name", new LocalizableError("picker.duplicity"));
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();
        }
        setUserLogin(picker.getLogin());
        setPassword(plainPass);
        return submitLogin();
    }
}
